package org.example.backend.controller;


import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import org.example.backend.common.Result;
import org.example.backend.entity.Users;
import org.example.backend.entity.Wallpapers;
import org.example.backend.mapper.UsersMapper;
import org.example.backend.mapper.WallpapersMapper;
import org.example.backend.util.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;

@RestController
@RequestMapping("/wallpaper")
public class WallpaperController {

    @Value("${wallpaper.upload.dir}")
    private String uploadDirPath;

    @Value("${wallpaper.public.url:/uploads/wallpaper/}")
    private String publicUrl;

    private String uploadDir;

    @Autowired
    private WallpapersMapper wallpapersMapper;

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private UsersMapper usersMapper;


    @PostConstruct
    private void init() throws IOException {
        try {
            Resource resource = new DefaultResourceLoader().getResource(uploadDirPath);
            File uploadDirFile = resource.getFile();
            if (!uploadDirFile.exists()) {
                uploadDirFile.mkdirs();
            }
            this.uploadDir = uploadDirFile.getAbsolutePath() + File.separator;

            // 创建缩略图目录
            File thumbnailDir = new File(uploadDirFile, "thumbnails");
            if (!thumbnailDir.exists()) {
                thumbnailDir.mkdirs();
            }
        } catch (IOException e) {
            throw new RuntimeException("无法初始化上传目录: " + e.getMessage(), e);
        }
    }


    @PostMapping("/{id}/download")
    public Result<Map<String, Object>> downloadWallpaper(
            @PathVariable Long id,
            @RequestParam(defaultValue = "original") String resolution,
            HttpServletRequest request
    ) {
        // 验证用户登录
        Cookie[] cookies = request.getCookies();
        String token = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("LINZEYO_AUTH".equals(cookie.getName())) {
                    token = cookie.getValue();
                    break;
                }
            }
        }

        if (token == null) {
            return Result.error("未登录或登录已过期");
        }

        try {
            // 验证token
            String username = tokenUtil.extractUsername(token);
            if (username == null) {
                return Result.error("无效的身份验证");
            }

            // 获取用户信息
            Users user = usersMapper.searchAllByUsername(username);
            if (user == null) {
                return Result.error("用户不存在");
            }

            // 查找壁纸
            Wallpapers wallpaper = wallpapersMapper.findAllById(id);
            if (wallpaper == null) {
                return Result.error("壁纸不存在");
            }

            // 检查付费壁纸权限
            if (wallpaper.getIs_premium() != null && wallpaper.getIs_premium() == 1) {
                if (!"admin".equals(user.getRole()) && !"premium".equals(user.getRole())) {
                    return Result.error("该壁纸需要高级会员才能下载");
                }
            }


            //TODO 其实我感觉挺多余的

            // 更新下载计数 - 修改这部分代码
            Integer downloadCount = wallpaper.getDownload_count();
            // 创建新对象，只包含需要更新的字段
            Wallpapers updateWallpaper = new Wallpapers();
            updateWallpaper.setId(id);
            updateWallpaper.setDownload_count(downloadCount);
            wallpapersMapper.updateDownloadCount(id); // 需要创建这个新方法


            // 处理下载链接和文件信息
            String downloadUrl = wallpaper.getFile_url();
            String fileName = wallpaper.getTitle();
            Integer fileSize = wallpaper.getFile_size();

// 检查downloadUrl是否为空
            if (downloadUrl == null) {
                return Result.error("壁纸下载链接不存在");
            }

// 根据分辨率处理
            switch (resolution) {
                case "1080p":
                    // 检查替换是否有效，避免返回null
                    if (downloadUrl.contains(publicUrl)) {
                        downloadUrl = downloadUrl.replace(publicUrl, publicUrl + "resized/1080p/");
                    } else {
                        // 如果不含publicUrl，则直接添加路径前缀
                        downloadUrl = downloadUrl + "?size=1080p";
                    }
                    fileName = fileName + "_1080p";
                    fileSize = fileSize == null ? 0 : (int)(fileSize * 0.7);
                    break;
                case "720p":
                    if (downloadUrl.contains(publicUrl)) {
                        downloadUrl = downloadUrl.replace(publicUrl, publicUrl + "resized/720p/");
                    } else {
                        downloadUrl = downloadUrl + "?size=720p";
                    }
                    fileName = fileName + "_720p";
                    fileSize = fileSize == null ? 0 : (int)(fileSize * 0.5);
                    break;
                case "mobile":
                    if (downloadUrl.contains(publicUrl)) {
                        downloadUrl = downloadUrl.replace(publicUrl, publicUrl + "resized/mobile/");
                    } else {
                        downloadUrl = downloadUrl + "?size=mobile";
                    }
                    fileName = fileName + "_mobile";
                    fileSize = fileSize == null ? 0 : (int)(fileSize * 0.4);
                    break;
            }

// 确保文件名包含扩展名
            String fileFormat = wallpaper.getFile_format();
            if (fileFormat != null && !fileName.toLowerCase().endsWith("." + fileFormat.toLowerCase())) {
                fileName += "." + fileFormat;
            } else if (fileFormat == null) {
                // 如果文件格式为空，使用默认格式
                fileName += ".jpg";
            }

            // 构建响应数据
            Map<String, Object> data = new HashMap<>();
            data.put("downloadUrl", downloadUrl);
            data.put("fileName", fileName);
            data.put("fileSize", fileSize);

            return Result.success("壁纸下载准备完成", data);
        } catch (Exception e) {
            return Result.error("下载准备失败: " + e.getMessage());
        }
    }

    /**
     * 获取壁纸列表
     * @param page 页码，默认1
     * @param size 每页数量，默认12
     * @param category 分类别名(slug)
     * @param tag 标签名称
     * @param width 筛选宽度
     * @param height 筛选高度
     * @param aspectRatio 筛选宽高比
     * @param isPremium 是否付费壁纸
     * @param keyword 搜索关键词
     * @param sort 排序方式
     * @return 壁纸列表及分页信息
     */
    @GetMapping("/list")
    public Result<Map<String, Object>> getWallpaperList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "12") Integer size,
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String tag,
            @RequestParam(required = false) Integer width,
            @RequestParam(required = false) Integer height,
            @RequestParam(required = false) String aspectRatio,
            @RequestParam(required = false) Boolean isPremium,
            @RequestParam(required = false) String keyword,
            @RequestParam(defaultValue = "newest") String sort
    ) {
        try {
            // 计算分页参数
            int offset = (page - 1) * size;

            // 构建查询条件
            // 这里应根据你的mapper方法来实现具体的查询逻辑
            List<Wallpapers> wallpapersList = wallpapersMapper.findWallpapers(
                    category, tag, width, height, aspectRatio,
                    isPremium, keyword, sort, offset, size);

            // 获取总记录数
            int total = wallpapersMapper.countWallpapers(
                    category, tag, width, height, aspectRatio,
                    isPremium, keyword);

            // 计算总页数
            int totalPages = (int) Math.ceil((double) total / size);

            // 转换为响应数据格式
            List<Map<String, Object>> items = new java.util.ArrayList<>();
            for (Wallpapers wallpaper : wallpapersList) {
                Map<String, Object> item = new HashMap<>();
                item.put("id", wallpaper.getId());
                item.put("title", wallpaper.getTitle());
                item.put("description", wallpaper.getDescription());
                item.put("thumbnailUrl", wallpaper.getThumbnail_url());
                item.put("width", wallpaper.getWidth());
                item.put("height", wallpaper.getHeight());
                item.put("aspectRatio", wallpaper.getAspect_ratio());
                item.put("fileFormat", wallpaper.getFile_format());
                item.put("fileSize", wallpaper.getFile_size());
                Integer isPremiumValue = wallpaper.getIs_premium();
                item.put("isPremium", isPremiumValue != null && isPremiumValue == 1);
                item.put("downloadCount", wallpaper.getDownload_count());
                item.put("viewCount", wallpaper.getView_count());
                item.put("likeCount", wallpaper.getLike_count());
                item.put("uploadedAt", wallpaper.getCreated_at());

                // 获取壁纸相关的标签和分类
                // 此处需要实现获取标签和分类的方法
                item.put("tags", getWallpaperTags(wallpaper.getId()));
                item.put("categories", getWallpaperCategories(wallpaper.getId()));

                items.add(item);
            }

            // 构建响应数据
            Map<String, Object> data = new HashMap<>();
            data.put("items", items);
            data.put("total", total);
            data.put("page", page);
            data.put("size", size);
            data.put("totalPages", totalPages);

            return Result.success("获取壁纸列表成功", data);
        } catch (Exception e) {
            return Result.error("获取壁纸列表失败: " + e.getMessage());
        }
    }

    // 辅助方法：获取壁纸标签
    private List<Map<String, Object>> getWallpaperTags(Long wallpaperId) {
        // 此处需要实现从数据库获取壁纸标签的逻辑
        // 示例返回格式
        List<Map<String, Object>> tags = new ArrayList<>();
        // TODO: 从数据库获取标签数据并填充
        return tags;
    }

    // 辅助方法：获取壁纸分类
    private List<Map<String, Object>> getWallpaperCategories(Long wallpaperId) {
        // 此处需要实现从数据库获取壁纸分类的逻辑
        // 示例返回格式
        List<Map<String, Object>> categories = new ArrayList<>();
        // TODO: 从数据库获取分类数据并填充
        return categories;
    }



    @PostMapping("/upload")
    public Result<Map<String,Object>> uploadWallpaper(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "title", required = false) String title,
            @RequestParam(value = "description", required = false) String description,
            @RequestParam(value = "is_premium", defaultValue = "0") Integer isPremium,
            HttpServletRequest request
    ) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            return Result.error("文件不能为空");
        }

        // 从cookie中获取token
        Cookie[] cookies = request.getCookies();
        String token = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("LINZEYO_AUTH".equals(cookie.getName())) {
                    token = cookie.getValue();
                    break;
                }
            }
        }

        if (token == null) {
            return Result.error("未登录或登录已过期");
        }

        // 从token中提取用户名
        String username;
        try {
            username = tokenUtil.extractUsername(token);
            if (username == null) {
                return Result.error("无效的身份验证");
            }
        } catch (Exception e) {
            return Result.error("令牌解析失败: " + e.getMessage());
        }

        // 通过用户名获取用户ID
        Users user = usersMapper.searchAllByUsername(username);
        if (user == null) {
            return Result.error("用户不存在");
        }

        Long uploaderId = user.getId();

        // 获取文件名
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            return Result.error("文件名不能为空");
        }

        // 检查文件格式
        String fileFormat = getFileExtension(fileName);
        if (!isValidImageFormat(fileFormat)) {
            return Result.error("不支持的文件格式，只允许jpg、png、webp格式");
        }

        try {
            // 确保目录存在
            Path dirPath = Paths.get(uploadDir);
            if (!Files.exists(dirPath)) {
                Files.createDirectories(dirPath);
            }

            // 确保缩略图目录存在
            Path thumbnailDirPath = Paths.get(uploadDir + "thumbnails/");
            if (!Files.exists(thumbnailDirPath)) {
                Files.createDirectories(thumbnailDirPath);
            }

            // 生成新文件名
            String newFileName = UUID.randomUUID().toString() + "." + fileFormat;
            File destFile = new File(uploadDir + newFileName);

            // 保存文件
            file.transferTo(destFile);

            // 获取图片尺寸
            BufferedImage image = ImageIO.read(destFile);
            int width = image.getWidth();
            int height = image.getHeight();

            // 生成缩略图（设置合适的缩略图尺寸，这里用原图的30%）
            int thumbWidth = Math.max(width / 3, 300); // 最小宽度为300px
            int thumbHeight = Math.max(height / 3, 300); // 最小高度为300px
            BufferedImage thumbnail = generateThumbnail(image, thumbWidth, thumbHeight);

            // 保存缩略图
            String thumbnailFileName = "thumbnails/thumb_" + newFileName;
            File thumbnailFile = new File(uploadDir + thumbnailFileName);
            ImageIO.write(thumbnail, fileFormat, thumbnailFile);

            // 创建壁纸记录
            Wallpapers wallpaper = new Wallpapers();
            wallpaper.setTitle(title != null ? title : fileName);
            wallpaper.setDescription(description);
            wallpaper.setFile_url(publicUrl + newFileName);
            wallpaper.setThumbnail_url(publicUrl + thumbnailFileName); // 设置缩略图URL
            wallpaper.setFile_size((int) file.getSize());
            wallpaper.setFile_format(fileFormat);
            wallpaper.setWidth(width);
            wallpaper.setHeight(height);
            // 不要设置aspect_ratio - 这是一个生成列
            wallpaper.setDownload_count(0);
            wallpaper.setView_count(0);
            wallpaper.setLike_count(0);
            wallpaper.setIs_premium(isPremium);
            wallpaper.setUploader_id(uploaderId);
            wallpaper.setCreated_at(new Date());
            wallpaper.setUpdated_at(new Date());
            wallpaper.setStatus(1);

            wallpapersMapper.insert(wallpaper);

            //构建响应数据
            Map<String, Object> data = new HashMap<>();
            data.put("id", wallpaper.getId());
            data.put("title", wallpaper.getTitle());
            data.put("thumbnailUrl", wallpaper.getThumbnail_url());

            return Result.success("上传成功", data);
        } catch (IOException e) {
            return Result.error("上传失败: " + e.getMessage());
        }
    }


    // 辅助方法：获取文件扩展名
    private String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1).toLowerCase();
    }

    // 辅助方法：验证图片格式
    private boolean isValidImageFormat(String format) {
        return format.equals("jpg") || format.equals("jpeg") ||
                format.equals("png") || format.equals("webp");
    }

    // 辅助方法：计算宽高比
    private String calculateAspectRatio(int width, int height) {
        if (width == 0 || height == 0) return "0:0";

        int gcd = findGCD(width, height);
        return (width / gcd) + ":" + (height / gcd);
    }

    // 辅助方法：计算最大公约数
    private int findGCD(int a, int b) {
        return b == 0 ? a : findGCD(b, a % b);
    }


    /**
     * 生成缩略图
     * @param originalImage 原始图片
     * @param width 缩略图宽度
     * @param height 缩略图高度
     * @return 缩略图BufferedImage
     */
    private BufferedImage generateThumbnail(BufferedImage originalImage, int width, int height) {
        BufferedImage thumbnailImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        java.awt.Graphics2D g2d = thumbnailImage.createGraphics();
        g2d.drawImage(originalImage.getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
        g2d.dispose();
        return thumbnailImage;
    }

    /**
     * 测试返回图片
     * @param id 壁纸ID
     * @return 壁纸详情
     */
}